#pragma once

#include <string>
#include <map>
#include "singleton.h"

template <class Base>
class BaseCreator
{
public:
	virtual Base *Create( ) = 0;
};

template <class Base, class Product>
class Creator:public BaseCreator<Base>
{
public:
	virtual Base *Create( )
	{
		Base *product = new Product;
		return product;
	}
};


template <class Base>
class ObjFactory:public CSingleton<ObjFactory<Base> >
{
	friend class CSingleton<ObjFactory>;
private:
		ObjFactory()
		{

		}
		~ObjFactory()
		{

		}
		ObjFactory( const ObjFactory& );
		ObjFactory& operator =(const ObjFactory&);
	typedef std::map<std::string, BaseCreator<Base>* > CreatorMap;
public:
	Base *Create( std::string name )
	{
		CreatorMap::iterator iter = mCreatorMap.find( name );
		if( iter != mCreatorMap.end() )
		{
			BaseCreator<Base> *creator = iter->second;
			return creator->Create();
		}
		return 0;
	}
	
	bool Register( std::string name, BaseCreator<Base> *creator )
	{
		if( creator == 0 )
			return false;
		CreatorMap::iterator iter = mCreatorMap.find( name );
		if( iter != mCreatorMap.end() )
		{
			BaseCreator<Base> *creator = iter->second;
			delete creator;
		}
		mCreatorMap[name] = creator;
		return true;
	}
protected:
	 CreatorMap mCreatorMap;
};